/**
 * Copyright 2011 Honeywell Federal Manufacturing & Technologies, LLC. This material was produced under U.S. Government
 * contract DE-ACO4-01AL66850, Honeywell Federal Manufacturing & Technologies, LLC, (FM&T) with the U. S. Department of
 * Energy for the operation of the Kansas City Plant . The U.S. Government has rights to use, reproduce, and distribute
 * this software.  NEITHER THE GOVERNMENT NOR Honeywell Federal Manufacturing & Technologies, LLC, MAKES ANY WARRANTY,
 * EXPRESS OR IMPLIED, OR ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE.  If software is modified to produce
 * derivative works, such modified software should be clearly marked, so as not to confuse it with the version available
 * from FM&T.
 *
 * Additionally, this program is free software; you can redistribute it and/or modify it under the terms of the GNU
 * General Public License Version 3 published by the Free Software Foundation. Accordingly, this program is distributed in
 * the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with this library.
 * If not, see http://www.gnu.org/licenses/.
 */
/**
 * NOTICE:  This computer software was prepared by Honeywell Federal Manufacturing &
 * Technologies, hereinafter the Contractor, under Contract NO. DE-AC04-01AL66850 with 
 * the U.S. Department of Energy (DOE).  All rights in the computer software are 
 * reserved by DOE on behalf of the United States Government and the Contractor as 
 * provided in the Contract.  You are authorized to use this program for Government 
 * purposes but it is not to be released or distributed to the public.  Neither the 
 * Government nor the Contractor makes any warranty, express or implied, or assumes 
 * any liability for the use of this software.  This notice including this sentence 
 * must appear on any copies of this computer software.
 */

package org.braintrain.tapestry.view;

import com.javaforge.tapestry.spring.annotations.InjectSpring;
import com.kcp.ko.applicationVersion.ManifestVersionNumberFactory;
import com.kcp.ko.fmtnmlib.service.search.SimpleSearch;
import org.apache.tapestry.IAsset;
import org.apache.tapestry.IExternalPage;
import org.apache.tapestry.IRequestCycle;
import org.apache.tapestry.annotations.*;
import org.apache.tapestry.bean.EvenOdd;
import org.apache.tapestry.services.DataSqueezer;
import org.apache.tapestry.valid.ValidationDelegate;
import org.braintrain.domain.HomeConfig;
import org.braintrain.domain.Module;
import org.braintrain.domain.Navigation;
import org.braintrain.services.DeltaResourceManager;
import org.braintrain.services.MediaService;
import org.braintrain.services.NavigationService;
import org.braintrain.services.search.ActiveModuleQueryFactory;
import org.braintrain.services.search.UnrestrictedModuleQueryFactory;
import org.braintrain.services.search.navigation.StartingNavigationQueryFactory;

import javax.servlet.ServletContext;
import java.util.Collections;
import java.util.List;

/**
 * The Tapestry Home page.  This page shows the current modules available to the user.  Also, 
 * gives the admin users access to add new modules, add new users or edit the header.
 * 
 * @author John Ericksen
 *
 */

public abstract class Home extends BrainTrainSecuredBasePage implements IExternalPage {
    
    //Image Assets
    @Asset("/images/add.gif")
    public abstract IAsset getAddImage(); 
    
    @Asset("/images/rootHome.gif")
    public abstract IAsset getRootHomeImage();
    
    @Asset("/images/edit.gif")
    public abstract IAsset getEditImage(); 
    
    @Asset("/images/lightning.gif")
    public abstract IAsset getConnectedImage(); 
    
    @Asset("/images/smallsubject.gif")
    public abstract IAsset getUserImage(); 
    
    @Asset("/images/emailEdit.gif")
    public abstract IAsset getEmailEditImage();
    
    @Asset("/images/module.gif")
    public abstract IAsset getModuleImage(); 
    
    @InjectObject("service:tapestry.data.DataSqueezer")
    public abstract DataSqueezer getDataSqueezer();
    
    @Bean
    public abstract EvenOdd getEvenOdd();
    
    @Bean
    public abstract ValidationDelegate getDefaultDelegate();
    
    @Persist("session:page")
    public abstract boolean getEditHeader();
    public abstract void setEditHeader(boolean b);
    
    //Loop Variable
    public abstract Module getModule();
    public abstract void setModule(Module m);
    
    //Page Injections
    @InjectPage("ModuleAdmin")
    public abstract ModuleAdmin getModuleAdminPage();
    
    @InjectPage("UserAdmin")
    public abstract UserAdmin getUserAdminPage();
    
    @InjectPage("View")
    public abstract View getViewPage();
    
    @InjectPage("SkipFinishedChapters")
    public abstract SkipFinishedChapters getSkipFinishedChaptersPage();
    
    @InjectSpring("mediaService")
    public abstract MediaService getMediaService();
    
    @InjectSpring("navigationService")
    public abstract NavigationService getNavigationService();

    @InjectSpring("resourceManager")
    public abstract DeltaResourceManager getResourceManager();

    /**
     * ServletContext Hivemind injection
     *
     * @return ServletContext
     */
    @InjectObject("service:tapestry.globals.ServletContext")
    public abstract ServletContext getServletContext();
    
    public abstract String getCurrentEditedContent();
    public abstract void setCurrentEditedContent(String c);
    
    //activate externally
    public void activateExternalPage(Object[] params, IRequestCycle cycle) {
        cycle.activate(this);
    }
    
    
    
    /**
     * Returns a list of the available modules.  This list, of course, depends upon
     * the user's role in the system
     * 
     * @return
     */
    public List<Module> getModules()
    {
        getGenericService().clearSession();
        List<Module> modules = null;
        
        if(isCmStaff())
        {
            //CM-Staff get everything
            modules = getGenericService().getAll(Module.class);
        }
        else if(isContentCreator())
        {
            //Content Creators see all non-retired modules
            modules = getGenericService().find(SimpleSearch.simpleObjectSearch(Module.class, "retired", false));
        }
        else
        {
            //Regular users see all active, non-retired modules.
            modules = getGenericService().find(new ActiveModuleQueryFactory(getBraintrainVisit().getUser()));
            modules.addAll(getGenericService().find(new UnrestrictedModuleQueryFactory()));
        }
        Collections.sort(modules);
        return modules;
    }
    
    
    
    /**
     * Link to add a new module (Module Admin)
     */
    public void addModule( IRequestCycle cycle ) 
    {       
        getModuleAdminPage().activate(cycle);
    }
    
    /**
     * Link to view the given module.  CMStaff and ContentCreators go to the moduleAdmin page,
     * Regular users go to either the first page or the SkipFinishedChapters page.
     * 
     */
    public void viewModule(IRequestCycle cycle)
    {
        Object[] paramters = cycle.getListenerParameters();
        if(paramters.length > 0 && paramters[0] instanceof Long)
        {
            if(isDeltaUser())
            {
                getModuleAdminPage().activate(cycle, (Long)paramters[0]);
            }
            else
            {
                Module module = (Module)getGenericService().getById(Module.class, (Long)paramters[0]);
                Navigation first = (Navigation) getGenericService().findUnique(new StartingNavigationQueryFactory(module, true, false, false));
                if(first != null)
                {
                    if(module.isSkipFinishedChapters())
                    {
                        getSkipFinishedChaptersPage().activate(cycle, module.getId());
                    }
                    else
                    {
                        ((BrainTrainEditableNavigatablePage)cycle.getPage(first.getType().name()))
                        .activate(cycle, first.getId(), null);
                    }
                }
            }
        }
    }
	
    /**
     * Edit Header
     */
    public void editHeaderSubmit(IRequestCycle cycle)
    {
        setEditHeader(true);
    }
    
    /**
     * Save the header (put the string into a blob and associate with the 'HomeConfig'.
     * @param cycle
     */
    public void saveHeaderSubmit(IRequestCycle cycle){
        String content = getContentService().parseHTMLBlobFile(getCurrentEditedContent(), getHomeConfig().getResource(), null, false, false, getDataSqueezer());
        getResourceManager().saveResourceValue(content, getHomeConfig().getResource());
    }
    
    /**
     * Cancel the edit (return home)
     * @param cycle
     */
    public void cancelHeaderSubmit(IRequestCycle cycle)
    {
        getGenericService().clearSession();
        config = null;
        setEditHeader(false);
       
        /*try {
            DatabaseBuilder builder = new DatabaseBuilder();
            
            builder.setService(getGenericService());

            builder.buildDatabase();

        } catch (Exception e) {
            e.printStackTrace();
        }*/
    }
    
    private HomeConfig config = null;
    
    /**
     * Get Home page config
     */
    private HomeConfig getHomeConfig()
    {
        if(getRequestCycle().isRewinding())
        {
            if(config == null)
            {
                List<HomeConfig> configList = (List<HomeConfig>)getGenericService().getAll(HomeConfig.class);
                
                //really, we shouldnt have more than 1 config in the table
                if(configList.size() > 0)
                {
                    config = configList.get(0);
                }
                else
                {
                    config = new HomeConfig();
                }
            }
            return config;
        }
        else
        {
            config = null;
            List<HomeConfig> configList = (List<HomeConfig>)getGenericService().getAll(HomeConfig.class);
            
            //really, we shouldn't have more than 1 config in the table
            if(configList.size() > 0)
            {
                return configList.get(0);
            }
            else
            {
                return new HomeConfig();
            }
        }
    }
    
    /**
     * Home Header getters/setters
     */
    public void setHomeHeader(String header)
    {
        setCurrentEditedContent(header);
    }
    
    public String getHomeHeader()
    {
        return getResourceManager().getResourceValue(getHomeConfig().getResource());
    }

     /**
     * Returns the Application version
     * @return application version string
     */
    public String getApplicationVersion(){
        return new ManifestVersionNumberFactory("BrainTrain").getShortApplicationVersion(getServletContext());
    }
}
